{extend name="layout" /}


{block name="title"}
<title>可重写方法 - thinkPHP极速后台开发</title>
<meta name="title" content="可重写方法 - thinkPHP极速后台开发">
<meta name="keywords" content="可重写方法,php,后台开发包，thinkphp、easyadmin、admin,easy,thinkeasyadmin">
<meta name="description" content="可重写方法一览;easyadmin灵活可定制的thinkphp的后台开发工具包,助你快速开发后台">
{/block}

{block name="main"}


<fieldset id="join" class="layui-elem-field">
    <legend>重写方法</legend>
    <div class="layui-field-box">
        <p>路由实现 , 可继承后重写</p>
        <pre class="php">{literal}
namespace easyadmin\app\traits;


use easyadmin\app\libs\ListQuery;
use easyadmin\app\libs\PageForm;
use easyadmin\app\libs\PageList;
use easyadmin\app\libs\PageShow;
use Exception as ExceptionAlias;
use think\db\exception\DataNotFoundException as DataNotFoundExceptionAlias;
use think\db\exception\DbException as DbExceptionAlias;
use think\db\exception\ModelNotFoundException as ModelNotFoundExceptionAlias;
use think\Exception;
use think\facade\Db;
use think\Request;
use think\Request as RequestAlias;
use think\response\Json as JsonAlias;

/**
 * 路由类
 * Trait CrudRoutersTrait
 * @package easyadmin\app\traits
 */
trait CrudRoutersTrait
{

    /**
     * @param RequestAlias $request
     * @return mixed
     * @throws DbExceptionAlias
     * @throws ExceptionAlias
     */
    public function lists(Request $request)
    {
        $this->request = $request;

        //实例化查询
        $listQuery = new ListQuery($this->request);
        //实例化数据表格
        $page = new PageList($this->getTableName(), $this->getPageName(), $this->pk);

        //配置字段
        $this->configList($page);
        $this->configListField($page->getField());
        $this->configListFilter($page->getFilter());

        //创建查询
        $listQuery->createQuery($page);

        //自定义查询相关
        $this->configListJoin($listQuery->getQuery(), $listQuery->getAlias());
        $this->configQuery($listQuery->getQuery(), $listQuery->getAlias());
        $this->configWhere($listQuery->getQuery(), $listQuery->getAlias());

        //查询没有被删除的
        $listQuery->softDelete($this->softDeleteField, $this->softDeleteBeforeVal);

        //配置分页
        $this->configListPagination($page->getPage());

        //获取结果
        $listQuery->listResult($page);

        return $page->fetch($this->getPageName(), [
            'table' => $page,
            'addAction' => $page->getActionAdd(),
        ]);

    }


    /**
     * 启用与禁用
     * @param RequestAlias $request
     * @return JsonAlias
     */
    public function enable(Request $request): JsonAlias
    {
        try {
            $this->request = $request;
            $id = $request->get('id');
            $field = $request->get('field');
            $value = $request->post('value', 0);

            if (empty($id) || empty($field)) throw new ExceptionAlias('缺少参数');

            /** @noinspection PhpDynamicAsStaticMethodCallInspection */
            $query = Db::table($this->getTableName());
            $res = $query->where($this->pk, $id)->save([$field => $value]);
            return $this->success([
                'res' => $res
            ]);
        } catch (ExceptionAlias $e) {
            return $this->error($e->getMessage());
        }

    }

    /**
     * 添加页面
     * @param RequestAlias $request
     * @return mixed|string
     * @throws Exception
     */
    public function add(Request $request): string
    {
        $this->request = $request;
        $page = new PageForm($this->getTableName(), $this->getPageName(), $this->pk);

        $this->configFormField($page);
        $this->configFormAction($page->getAction());

        return $page->fetch($this->getPageName(), [
            'forms' => $page->getFields(),
            'actions' => $page->getAction()
        ]);
    }

    /**
     * 修改页面
     * @param RequestAlias $request
     * @return mixed|string
     * @throws Exception
     */
    public function edit(Request $request): string
    {
        $id = $request->get($this->pk);
        if (empty($id)) throw new Exception("缺少{$this->pk}参数");
        $this->request = $request;
        $page = new PageForm($this->getTableName(), $this->getPageName(), $this->pk);
        $page->setId($id);

        $this->configFormField($page);
        $this->configFormAction($page->getAction());

        $page->createQuery();
        $this->formQuery($page->getQuery(), $page->getAlias());
        $data = $page->getResult();

        if (empty($data)) {
            throw new Exception("参数{$id},查找不到内容");
        }

        return $page->fetch($this->getPageName(), [
            'forms' => $page->getFields(),
            'actions' => $page->getAction()
        ]);
    }

    /**
     * 保存记录
     * @param RequestAlias $request
     * @return JsonAlias
     */
    public function form_save(Request $request): JsonAlias
    {
        try {
            $this->request = $request;
            $page = new PageForm($this->getTableName(), $this->getPageName(), $this->pk);
            $this->configFormField($page);
            $id = $request->post($this->pk);

            $form = $this->formRequestParam($page->getFields());

            $data = $this->formSave($form, $id);

            return $this->success($data);
        } catch (ExceptionAlias $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 查看详细页面
     * @param RequestAlias $request
     * @return mixed
     * @throws DataNotFoundExceptionAlias
     * @throws DbExceptionAlias
     * @throws ModelNotFoundExceptionAlias|Exception
     */
    public function show(Request $request)
    {
        $this->request = $request;
        $id = $request->get('id');
        if (empty($id)) {
            return redirect(url('lists'));
        }
        $show = new PageShow($this->getTableName(), $this->getPageName(), $this->pk);
        $show->createQuery($id);
        $this->configShowQuery($show->getQuery(), $show->getAlias());
        $this->configShow($show);
        $this->configShowField($show->getField());
        $this->configShowAction($show->getAction());
        $row = $show->getResult();

        return $show->fetch($this->getPageName(), [
            'result' => $row,
            'action' => $show->getAction(),
        ]);
    }


    /**
     * 删除一条数据
     * @param RequestAlias $request
     * @return mixed
     */
    public function delete(Request $request)
    {
        try {
            $this->request = $request;
            $id = $request->get('id');
            if (empty($id)) throw new ExceptionAlias('缺少参数');

            //创建查询
            /** @noinspection PhpDynamicAsStaticMethodCallInspection */
            $query = Db::table($this->getTableName())->where($this->pk, $id);

            //删除
            if ($this->softDeleteField) {
                //软删除
                $query->update([$this->softDeleteField => $this->softDeleteAfterVal]);
            } else {
                //直接删除
                $query->delete();
            }
            return $this->success([
                'url' => url('lists')
            ]);
        } catch (ExceptionAlias $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 搜索下拉框, 搜索值
     * @param RequestAlias $request
     * @return mixed
     * @throws DbExceptionAlias
     * @throws DataNotFoundExceptionAlias
     * @throws ModelNotFoundExceptionAlias
     * @noinspection PhpUnused
     */
    public function autocomplete_select(Request $request)
    {
        $pk = $request->get('pk');
        $table = $request->get('table');
        $property = $request->get('property');
        $search = $request->get('search');
        $default = $request->get('default');

        if (empty($pk) || empty($table) || empty($property)) {
            return $this->error('缺少参数');
        }

        /** @noinspection PhpDynamicAsStaticMethodCallInspection */
        $query = Db::table($table)->field("`{$pk}`,`{$property}`")->limit(30);
        if ($search) {
            $query->where($property, 'like', "%{$search}%");
        }
        if ($default) {
            $query->where($pk, $default);
        }

        $res = $query->select();
        $result = [];
        foreach ($res as $item) {
            array_push($result, [
                'value' => $item[$pk],
                'name' => $item[$property],
            ]);
        }

        return $this->success($result);

    }

}

{/literal}</pre>
        <p>配置默认实现,可继承后重写</p>
        <pre class="php">{literal}
namespace easyadmin\app\traits;

use easyadmin\app\columns\form\BaseForm;
use easyadmin\app\columns\form\FormHidden;
use easyadmin\app\columns\form\FormText;
use easyadmin\app\columns\lists\ListText;
use easyadmin\app\libs\Page;
use easyadmin\app\libs\Btn;
use easyadmin\app\libs\Actions;
use easyadmin\app\libs\ListField;
use easyadmin\app\libs\ListFilter;
use easyadmin\app\libs\PageForm;
use easyadmin\app\libs\PageList;
use easyadmin\app\libs\Pagination;
use easyadmin\app\libs\PageShow;
use think\db\exception\DataNotFoundException as DataNotFoundExceptionAlias;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException as ModelNotFoundExceptionAlias;
use think\db\Query;
use think\Exception as ExceptionAlias;
use think\facade\Db;

/**
 * CRUD 开放出去的重写接口
 * Trait CrudRewriteTrait
 * @package easyadmin\app\traits
 */
trait CrudRewriteTrait
{

    /**
     * 定义列表的默认按钮
     * @param PageList $page
     */
    protected function configList(PageList $page)
    {
        $page->addAction('查看', 'show', [
            'icon' => 'layui-icon layui-icon-release',
            'class' => ['layui-btn-primary', 'layui-btn-xs'],
        ])->addAction('编辑', 'edit', [
            'icon' => 'layui-icon layui-icon-edit',
            'class' => ['layui-btn-primary', 'layui-btn-xs']
        ])->addAction('删除', 'delete', [
            'icon' => 'layui-icon layui-icon-delete',
            'class' => ['layui-btn-danger', 'layui-btn-xs'],
            'confirm' => '确定要删除数据吗?',
        ]);

        $addBtn = new Btn();
        $addBtn->setLabel('添加');
        $addBtn->setUrl('add');
        $addBtn->setIcon('layui-icon layui-icon-add-1');
        $page->setActionAdd($addBtn);
    }

    /**
     * 定义列表字段
     * @param ListField $list
     */
    protected function configListField(ListField $list)
    {
        //默认查询数据库的字段添加上去
        /** @noinspection PhpUndefinedMethodInspection */
        $fields = Db::query("show full columns from {$this->getTableName()}");

        foreach ($fields as $field) {
            //设置主键
            if ($field['Key'] === 'PRI') {
                $this->pk = $field['Field'];
            }
            //添加字段
            $list->addField($field['Field'], $field['Field'], ListText::class);
        }

    }

    /**
     * 设置分页相关
     * @param Pagination $page
     */
    protected function configListPagination(Pagination $page)
    {

    }

    /**
     * 列表查询设置 join
     * @param Query $query
     * @param string $alias 主表的别名
     */
    protected function configListJoin(Page $page, Query $query, string $alias)
    {

    }

    /**
     * 定义列表过滤器
     * @param ListFilter $filter
     */
    protected function configListFilter(ListFilter $filter)
    {
        $filter->addFilter('_query_', ' ', FormText::class);
    }

    /**
     * 自定义查询
     * @param Query $query
     * @param $alias
     */
    protected function configQuery(Query $query, $alias)
    {

    }

    /**
     * 设置查询条件
     * @param Query $query
     * @param $alias
     */
    protected function configWhere(Query $query, $alias)
    {

    }

    /**
     * 查看详情配置
     * @param PageShow $page
     */
    protected function configShow(PageShow $page)
    {
    }

    /**
     * 查看字段配置
     * @param ListField $field
     * @throws DataNotFoundExceptionAlias
     * @throws DbException
     * @throws ModelNotFoundExceptionAlias
     * @noinspection PhpUndefinedClassInspection
     */
    protected function configShowField(ListField $field)
    {
        $id = $this->request->get('id');
        if (empty($id)) return;
        /** @noinspection PhpDynamicAsStaticMethodCallInspection */
        $res = Db::table($this->getTableName())->where($this->pk, $id)->find();
        if (empty($res)) return;

        foreach ($res as $key => $val) {
            $field->addField($key, $key, ListText::class);
        }

    }


    /**
     * 查看详情按钮配置
     * @param Actions $action
     * @throws ExceptionAlias
     */
    protected function configShowAction(Actions $action)
    {
        $id = $this->request->get($this->pk);
        if (empty($id)) return;

        $params = [
            $this->pk => $id
        ];

        $action
            ->addAction('返回', 'javascript:', [
                'icon' => 'layui-icon layui-icon-return',
                'class' => ['layui-btn-primary'],
                'params' => $params,
                'referer' => true,
            ])
            ->addAction('编辑', 'edit', [
                'icon' => 'layui-icon layui-icon-edit',
                'class' => [''],
                'params' => $params
            ])
            ->addAction('删除', 'delete', [
                'icon' => 'layui-icon layui-icon-delete',
                'class' => ['layui-btn-danger'],
                'confirm' => '确定要删除数据吗?',
                'params' => $params
            ]);
    }


    /**
     * 详情 查询语句
     * @param Query $query
     * @param $alias
     */
    protected function configShowQuery(Query $query, $alias)
    {

    }

    /**
     * 设置表单字段
     * @param PageForm $page
     */
    protected function configFormField(PageForm $page)
    {
        /** @noinspection PhpUndefinedMethodInspection */
        $res = Db::query("show full fields from {$this->getTableName()}");
        if (empty($res)) return;

        foreach ($res as $item) {
            $field = $item['Field'];
            $class = FormText::class;
            if ($field == $this->pk) {
                $class = FormHidden::class;
            }
            $page->addField($field, $field, $class);
        }

    }


    /**
     * 添加和更新页面的操作按钮
     * @param Actions $action
     * @throws ExceptionAlias
     */
    protected function configFormAction(Actions $action)
    {
        $id = $this->request->get($this->pk);

        $params = [];
        if ($id) {
            $params[$this->pk] = $id;
        }

        $action
            ->addAction('取消', 'window.history.back();', [
                'icon' => 'layui-icon layui-icon-return',
                'class' => 'layui-btn-primary',
                'params' => $params,
            ])
            ->addAction($id ? '更新' : '添加', 'javascript:', [
                'icon' => 'layui-icon layui-icon-ok',
                'params' => $params,
                'btn_type' => 'submit',
                'referer' => true
            ]);

        if ($id) {
            $action->addAction('删除', 'delete', [
                'icon' => 'layui-icon layui-icon-delete',
                'class' => ['layui-btn-danger'],
                'confirm' => '确定要删除数据吗?',
                'params' => $params,
                'referer' => true
            ]);
        }

    }

    /**
     * form 表单接收参数
     * @param $fields
     * @return array
     */
    protected function formRequestParam($fields): array
    {
        $form = [];
        /** @var BaseForm $field */
        foreach ($fields as $field) {
            $field->requestValue($form);
        }
        return $this->requestAfter($form);
    }


    /**
     * 表单保存数据
     * @param $data
     * @param $id
     * @return int|mixed|string
     * @throws DbException
     * @noinspection PhpUndefinedClassInspection
     */
    protected function formSave($data, $id)
    {
        if ($id) {
            return $this->formUpdate($data, $id);
        } else {
            return $this->formInsert($data);
        }
    }

    /**
     * 表单写入
     * @param $data
     * @return array
     */
    protected function formInsert($data): array
    {
        $data = $this->verifyData($data);
        $data = $this->insertBefore($data);
        /** @noinspection PhpDynamicAsStaticMethodCallInspection */
        $id = Db::name($this->getTableName())->insertGetId($data);
        $data[$this->pk] = $id;
        $data = $this->insertAfter($data);
        return $data;
    }

    /**
     * 表单新增
     * @param $data
     * @param $id
     * @return mixed
     * @throws DbException
     * @noinspection PhpDynamicAsStaticMethodCallInspection
     * @noinspection PhpUndefinedClassInspection
     */
    protected function formUpdate($data, $id)
    {
        $data = $this->verifyData($data);
        $data = $this->updateBefore($data);
        Db::name($this->getTableName())
            ->where($this->pk, $id)
            ->update($data);
        $data[$this->pk] = $id;
        $data = $this->updateAfter($data);
        return $data;
    }

    //接收参数之后执行, post 接收到参数以后就调用
    protected function requestAfter($data): array
    {
        return $data;
    }

    //写入之前执行, 调用 insert 写入方法之前调用
    protected function insertBefore($data): array
    {
        return $data;
    }

    //写入之后执行,调用 insert 写入方法之后调用
    protected function insertAfter($data): array
    {
        return $data;
    }

    //更新之前执行, 调用 update 更新方法之前调用
    protected function updateBefore($data): array
    {
        return $data;
    }

    //更新之后执行, 调用 update 更新方法之后调用
    protected function updateAfter($data): array
    {
        return $data;
    }

    //添加和更新 数据验证
    // 在 requestAfter 之后 insertBefore updateBefore 之前执行
    protected function verifyData($data): array
    {
        return $data;
    }

    //更新页面的查询语句
    protected function formQuery(Query $query, $alias)
    {

    }

}

{/literal}</pre>
    </div>
</fieldset>


{/block}
